<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML><HEAD><TITLE>lua-users wiki: Module Definition</TITLE>
<LINK TYPE="text/css" REL="stylesheet" HREF="/styles/main.css">
</HEAD>
<BODY ><table width="100%" border="0"> <tr><td align=left width="100%"><h1><a href="/cgi-bin/wiki.pl?action=search&amp;string=ModuleDefinition&amp;body=1" title="List pages referring to ModuleDefinition">Module Definition</a></h1></td><td align=right>
    <table cellpadding="0" cellspacing="0" border="0" width="1%">
      <tbody>
        <tr>
            <td><a href="/">
            <img src="/images/nav-logo.png" alt="lua-users home" width="177" height="40" border="0"></a></td>
        </tr>
        <tr>
            <td>
            <table cellpadding="0" cellspacing="0" border="0" width="100%">
                <tbody>
                <tr>
                    <td><img src="/images/nav-elbow.png" alt="" width="48" height="40"></td>
                    <td nowrap valign="middle" width="100%">
                        <a href="/wiki/" class="nav">wiki</a></td>
                </tr>
                </tbody>
            </table>
            </td>
        </tr>
      </tbody>
    </table>
</td></tr> </table>
<br clear=all>
There are many ways to define a "module"<a href="http://en.wikipedia.org/wiki/Modularity_%28programming%29">[1]</a> in Lua.<p>
<H2>From a Table</H2>
<p>
<DL>
<dt><dd><pre class="code">
<span class="comment">-- mymodule.lua</span>
<span class="keyword">local</span> M = {} <span class="comment">-- public interface</span>

<span class="comment">-- private</span>
<span class="keyword">local</span> x = 1
<span class="keyword">local</span> <span class="keyword">function</span> baz() <span class="library">print</span> <span class="string">'test'</span> <span class="keyword">end</span>

<span class="keyword">function</span> M.foo() <span class="library">print</span>(<span class="string">"foo"</span>, x) <span class="keyword">end</span>

<span class="keyword">function</span> M.bar()
  M.foo()
  baz()
  <span class="library">print</span> <span class="string">"bar"</span>
<span class="keyword">end</span>

<span class="keyword">return</span> M

<span class="comment">-- Example usage:</span>
<span class="keyword">local</span> MM = <span class="library">require</span> <span class="string">'mymodule'</span>
MM.bar()
</pre>
</DL>
<p>
This is a common approach.  It is simple, relies on no external code, avoids globals, and has few pitfalls.  Externally facing variables are prefixed by "<code>M.</code>" and clearly seen.<p>
<H2>Using the <code>module</code> Function</H2>
<p>
<DL>
<dt><dd><pre class="code">
<span class="library">module</span>(..., <span class="library">package.seeall</span>)  <span class="comment">-- optionally omitting package.seeall if desired</span>

<span class="comment">-- private</span>
<span class="keyword">local</span> x = 1
<span class="keyword">local</span> <span class="keyword">function</span> baz() <span class="library">print</span> <span class="string">'test'</span> <span class="keyword">end</span>

<span class="keyword">function</span> foo() <span class="library">print</span>(<span class="string">"foo"</span>, x) <span class="keyword">end</span>

<span class="keyword">function</span> bar()
  foo()
  baz()
  <span class="library">print</span> <span class="string">"bar"</span>
<span class="keyword">end</span>

<span class="comment">-- Example usage:</span>
<span class="library">require</span> <span class="string">'mymodule'</span>
mymodule.bar()
</pre>
</DL>
<p>
This is also common and shorter.  It uses Lua's <code>module</code> function.  Some other ways of using the <code>module</code> function are in <em>Programming in Lua</em><a href="http://www.inf.puc-rio.br/~roberto/pil2/">[2]</a>.  However, see <a href="/wiki/LuaModuleFunctionCritiqued" >LuaModuleFunctionCritiqued</a> for criticisms of this approach.<p>
<H2>From a Table - Using Locals Internally</H2>
<p>
<DL>
<dt><dd><pre class="code">
<span class="keyword">local</span> M = {}

<span class="comment">-- private</span>
<span class="keyword">local</span> x = 1
<span class="keyword">local</span> <span class="keyword">function</span> baz() <span class="library">print</span> <span class="string">'test'</span> <span class="keyword">end</span>

<span class="keyword">local</span> <span class="keyword">function</span> foo() <span class="library">print</span>(<span class="string">"foo"</span>, x) <span class="keyword">end</span>
M.foo = foo

<span class="keyword">local</span> <span class="keyword">function</span> bar()
  foo()
  baz()
  <span class="library">print</span> <span class="string">"bar"</span>
<span class="keyword">end</span>
M.bar = bar

<span class="keyword">return</span> M
</pre>
</DL>
<p>
This is similar to the table approach, but even inside the module itself it uses lexicals when referring to externally faced variables.  Although this code is more verbose (repetitive), lexicals can be more efficient for performance critical code and more suitable for static analysis approaches to <a href="/wiki/DetectingUndefinedVariables" >DetectingUndefinedVariables</a>.  Futhermore, this approach prevents changes made to <code>M</code>--e.g. from a client--from affecting the behavior inside the module; for example, in the regular tables approach, <code>M.bar()</code> internally calls <code>M.foo()</code>, so the behavior of <code>M.bar()</code> will change if <code>M.foo()</code> were replaced.  This has some implications for <a href="/wiki/SandBoxes" >SandBoxes</a> too, and it is the reason for the extra locals in <code>etc/strict.lua</code> in Lua 5.1.3.<p>
<H2>localmodule</H2>
<p>
<DL>
<dt><dd><pre class="code">
<span class="keyword">local</span> M = {}

<span class="keyword">local</span> x = 1  <span class="comment">-- private</span>

<span class="keyword">local</span> M_baz = 1  <span class="comment">-- public</span>

<span class="keyword">local</span> <span class="keyword">function</span> M_foo()
  M_baz = M_baz + 1
  <span class="library">print</span> (<span class="string">"foo"</span>, x, M_baz)
<span class="keyword">end</span>

<span class="keyword">local</span> <span class="keyword">function</span> M_bar()
  M_foo()
  <span class="library">print</span> <span class="string">"bar"</span>
<span class="keyword">end</span>

<span class="library">require</span> <span class="string">'localmodule'</span>.export(M)

<span class="keyword">return</span> M

<span class="comment">-- Example usage:</span>
<span class="keyword">local</span> MM = <span class="library">require</span> <span class="string">'mymodule'</span>
MM.baz = 10
MM.bar()
MM.foo = <span class="keyword">function</span>() <span class="library">print</span> <span class="string">'hello'</span> <span class="keyword">end</span>
MM.bar()

<span class="comment">-- Output:</span>
<span class="comment">-- foo     1       11</span>
<span class="comment">-- bar</span>
<span class="comment">-- hello</span>
<span class="comment">-- bar</span>
</pre>
</DL>
<p>
This approach is more novel.  It defines all externally facing variables in the module using lexical (local) variables.  It makes heavy use of lexicals.  Reliance on lexicals has some advantages such as when using the static analysis methods of <a href="/wiki/DetectingUndefinedVariables" >DetectingUndefinedVariables</a>.  <p>
The <code>export</code> function uses the <code>debug</code> module to read the current function's local variables prefixed by <code>M_</code> (<code>debug.getlocal</code>) and expose them (read/write) through the module table <code>M</code> via metafunctions.  The ability to write to these variables is made possible by searching for and using (whenever possible) the upvalues located in closures (<code>debug.getupvalue/debug.getupvalue</code>), such as in the nested closures.  This avoids the repetition seen in "From a Table - Using Locals Internally".  You may selectively replace <code>M_foo</code> style references with <code>M.foo</code> style references if more dynamic behavior is desired.<p>
The implementation of <code>localmodule</code> assumes that symbols have not been stripped (luac -s) and that the debug module has not been removed, so this approach does have a bit more baggage.<p>
The <code>localmodule</code> module is defined as<p>
<DL>
<dt><dd><pre class="code">
<span class="comment">-- localmodule.lua</span>
<span class="comment">-- David Manura, 2008-03, Licensed under the same terms as Lua itself (MIT License).</span>
<span class="keyword">local</span> M = {}

<span class="comment">-- Creates metatable.</span>
<span class="keyword">local</span> getupvalue = <span class="library">debug.getupvalue</span>
<span class="keyword">local</span> setupvalue = <span class="library">debug.setupvalue</span>
<span class="keyword">local</span> <span class="keyword">function</span> makemt(t)
  <span class="keyword">local</span> mt = <span class="library">getmetatable</span>(t)
  <span class="keyword">if</span> <span class="keyword">not</span> mt <span class="keyword">then</span>
    mt = {}
    <span class="library">setmetatable</span>(t, mt)
  <span class="keyword">end</span>
  <span class="keyword">local</span> varsf,varsi = {},{}
  <span class="keyword">function</span> mt.__index(_,k)
    <span class="keyword">local</span> a = varsf[k]
    <span class="keyword">if</span> a <span class="keyword">then</span>
      <span class="keyword">local</span> _,val = getupvalue(a,varsi[k])
      <span class="keyword">return</span> val
    <span class="keyword">end</span>
  <span class="keyword">end</span>
  <span class="keyword">function</span> mt.__newindex(_,k,v)
    <span class="keyword">local</span> a = varsf[k]
    <span class="keyword">if</span> a <span class="keyword">then</span>
      setupvalue(a,varsi[k], v)
    <span class="keyword">end</span>
  <span class="keyword">end</span>
  <span class="keyword">return</span> varsf,varsi
<span class="keyword">end</span>

<span class="comment">-- Makes locals in caller accessible via the table P.</span>
<span class="keyword">local</span> <span class="keyword">function</span> export(P)
  P = P <span class="keyword">or</span> {}

  <span class="keyword">local</span> varsf,varsi = makemt(P)

  <span class="comment">-- For each local variable, attempt to locate an upvalue</span>
  <span class="comment">-- for it in one of the local functions.</span>
  <span class="comment">--</span>
  <span class="comment">-- TODO: This may have corner cases. For example, we might want to</span>
  <span class="comment">-- check that these functions are lexically nested in the current</span>
  <span class="comment">-- function (possibly with something like lbci).</span>
  <span class="keyword">for</span> i=1,<span class="library">math.huge</span> <span class="keyword">do</span>
    <span class="keyword">local</span> name,val = <span class="library">debug.getlocal</span>(2, i)
    <span class="keyword">if</span> val == <span class="keyword">nil</span> <span class="keyword">then</span> <span class="keyword">break</span> <span class="keyword">end</span>
    <span class="keyword">if</span> <span class="library">type</span>(val) == <span class="string">'function'</span> <span class="keyword">then</span>
      <span class="keyword">local</span> f = val
      <span class="keyword">for</span> j=1,<span class="library">math.huge</span> <span class="keyword">do</span>
        <span class="keyword">local</span> name,val = <span class="library">debug.getupvalue</span>(f, j)
        <span class="keyword">if</span> val == <span class="keyword">nil</span> <span class="keyword">then</span> <span class="keyword">break</span> <span class="keyword">end</span>
        <span class="keyword">if</span> name:find(<span class="string">"M_"</span>) == 1 <span class="keyword">then</span>
          name = name:sub(3)
          varsf[name] = f
          varsi[name] = j
          <span class="comment">--print('DEBUG:upvalue', name)</span>
        <span class="keyword">end</span>
      <span class="keyword">end</span>
    <span class="keyword">end</span>
  <span class="keyword">end</span>

  <span class="comment">-- For each local variable, it no upvalue was found, just</span>
  <span class="comment">-- resort to making a copy of it instead.</span>
  <span class="keyword">for</span> i=1,<span class="library">math.huge</span> <span class="keyword">do</span>
    <span class="keyword">local</span> name,val = <span class="library">debug.getlocal</span>(2, i)
    <span class="keyword">if</span> val == <span class="keyword">nil</span> <span class="keyword">then</span> <span class="keyword">break</span> <span class="keyword">end</span>
    <span class="keyword">if</span> name:find(<span class="string">"M_"</span>) == 1 <span class="keyword">then</span>
      name = name:sub(3)
      <span class="keyword">if</span> <span class="keyword">not</span> varsf[name] <span class="keyword">then</span>
        <span class="library">rawset</span>(P, name, val)
        <span class="comment">--print('DEBUG:copy', name)</span>
      <span class="keyword">end</span>
    <span class="keyword">end</span>
  <span class="keyword">end</span>

  <span class="keyword">return</span> P
<span class="keyword">end</span>
M.export = export

<span class="keyword">return</span> M
</pre>
</DL>
<p>
<H2>Pattern: Module System with Public/Private Namespaces</H2>
<p>
As noted in Programming in Lua, 2nd edition p.144, when using the Lua 5.1 module system with the <code>package.seeall</code> option (or the equivalent <code>setmetatable(M, {__index = _G})</code> trick), there is a peculiarity in that global variables are accessible through the module table.  For example, if you have a module named <code>complex</code> defined as such:<p>
<DL>
<dt><dd><pre class="code">
<span class="comment">-- complex.lua</span>
<span class="library">module</span>(<span class="string">"complex"</span>, <span class="library">package.seeall</span>)
<span class="comment">-- ...</span>
</pre>
</DL>
<p>
then doing<p>
<DL>
<dt><dd><pre class="code">
<span class="library">require</span> <span class="string">"complex"</span>
<span class="library">print</span>(complex.math.sqrt(2))
</pre>
</DL>
<p>
prints the square root of 2 because <code>math</code> is a global variable.  Furthermore, if a global variable with name <code>complex</code> already exists (possibly defined in some unrelated file), then the <code>require</code> will fail:<p>
<DL>
<dt><dd><pre>
-- put this in the main program:
complex = 123
-- then deep in some module do this:
local c = require "complex"
--&gt; fails with "name conflict for module 'complex'"
</pre></DL>
<p>
This is a type of namespace pollution and possibly a source of errors.<p>
The problem as I see it is that the environment used internally by the module is the same as the table exposed to the client of the module.  We can make these two separate tables as given in the below solution:<p>
<DL>
<dt><dd><pre class="code">
<span class="comment">-- cleanmodule.lua</span>

<span class="comment">-- Declare module cleanly.</span>
<span class="comment">-- Create both public and private namespaces for module.</span>
<span class="comment">-- Global assignments inside module get placed in both</span>
<span class="comment">-- public and private namespaces.</span>
<span class="keyword">function</span> cleanmodule(modname)
  <span class="keyword">local</span> pub = {}     <span class="comment">-- public namespace for module</span>
  <span class="keyword">local</span> priv = {}  <span class="comment">-- private namespace for module</span>
  <span class="keyword">local</span> privmt = {}
  privmt.__index = <span class="library">_G</span>
  privmt.__newindex = <span class="keyword">function</span>(priv, k, v)
    <span class="comment">--print("DEBUG:add",k,v)</span>
    <span class="library">rawset</span>(pub, k, v)
    <span class="library">rawset</span>(priv, k, v)
  <span class="keyword">end</span>
  <span class="library">setmetatable</span>(priv, privmt)
  <span class="library">setfenv</span>(2, priv)

  <span class="library">package.loaded</span>[modname] = pub
<span class="keyword">end</span>

<span class="comment">-- Require module, but store module only in</span>
<span class="comment">-- private namespace of caller (not public namespace).</span>
<span class="keyword">function</span> cleanrequire(name)
  <span class="keyword">local</span> result = <span class="library">require</span>(name)
  <span class="library">rawset</span>(<span class="library">getfenv</span>(2), name, result)
  <span class="keyword">return</span> result
<span class="keyword">end</span>
</pre>
</DL>
<p>
Example usage:<p>
<DL>
<dt><dd><pre class="code">
<span class="comment">-- test.lua</span>
<span class="library">require</span> <span class="string">"cleanmodule"</span>

m2 = 123  <span class="comment">-- variable that happens to have same name as a module</span>

cleanrequire <span class="string">"m1"</span>

m1.test()

<span class="library">assert</span>(m1)
<span class="library">assert</span>(<span class="keyword">not</span> m1.m2)  <span class="comment">-- works correctly!</span>
<span class="library">assert</span>(m1.test)
<span class="library">assert</span>(m1.helper)

<span class="library">assert</span>(m2 == 123)  <span class="comment">-- works correctly!</span>

<span class="library">print</span>(<span class="string">"done"</span>)
</pre>
</DL>
<p>
<DL>
<dt><dd><pre class="code">
<span class="comment">-- m1.lua</span>
cleanmodule(...)

cleanrequire <span class="string">"m2"</span>

<span class="keyword">function</span> helper()
  <span class="library">print</span>(<span class="string">"123"</span>)
<span class="keyword">end</span>

<span class="keyword">function</span> test()
  helper()
  m2.test2()
<span class="keyword">end</span>

<span class="library">assert</span>(<span class="keyword">not</span> m1)
<span class="library">assert</span>(test)
<span class="library">assert</span>(helper)

<span class="library">assert</span>(m2)
<span class="library">assert</span>(m2.test2)
<span class="library">assert</span>(<span class="keyword">not</span> m2.m1)
<span class="library">assert</span>(<span class="keyword">not</span> m2.m2)
</pre>
</DL>
<p>
<DL>
<dt><dd><pre class="code">
<span class="comment">-- m2.lua</span>
cleanmodule(...)

<span class="keyword">function</span> test2()
  <span class="library">print</span>(234)
<span class="keyword">end</span>
</pre>
</DL>
<p>
Output:<DL>
<dt><dd><pre>
123
234
done
</pre></DL>
<p>
<strong>Take #2</strong> - Here is the latest refinement of the previous code.  This version only replaces <code>module</code> not <code>require</code>.<p>
<DL>
<dt><dd><pre class="code">
<span class="comment">-- cleanmodule.lua</span>

<span class="comment">-- Helper function added to modules defined by cleanmodule</span>
<span class="comment">-- to support importing module symbols into client namespace.</span>
<span class="comment">-- Usage:</span>
<span class="comment">--   local mm = require "mymodule"  -- only local exported</span>
<span class="comment">--   require "mymodule" ()          -- export module table to environment</span>
<span class="comment">--   require "mymodule" ":all"      -- export also all functions</span>
<span class="comment">--                                     to environment.</span>
<span class="comment">--   require "mymodule" (target,":all")  -- export instead to given table</span>
<span class="keyword">local</span> <span class="keyword">function</span> import(public, ...)
  <span class="comment">-- Extract arguments.</span>
  <span class="keyword">local</span> target, options = ...
  <span class="keyword">if</span> <span class="library">type</span>(target) ~= <span class="string">"table"</span> <span class="keyword">then</span>
    target, options = <span class="keyword">nil</span>, target
  <span class="keyword">end</span>
  target = target <span class="keyword">or</span> <span class="library">getfenv</span>(2)

  <span class="comment">-- Export symbols.</span>
  <span class="keyword">if</span> options == <span class="string">":all"</span> <span class="keyword">then</span>
    <span class="keyword">for</span> k,v <span class="keyword">in</span> <span class="library">pairs</span>(public) <span class="keyword">do</span> target[k] = v <span class="keyword">end</span>
  <span class="keyword">end</span>

  <span class="comment">-- Build public module tables in caller.</span>
  <span class="keyword">local</span> prevtable, prevprevtable, prevatom = target, <span class="keyword">nil</span>, <span class="keyword">nil</span>
  public._NAME:gsub(<span class="string">"[^%.]+"</span>, <span class="keyword">function</span>(atom)
    <span class="keyword">local</span> <span class="library">table</span> = <span class="library">rawget</span>(prevtable, atom)
    <span class="keyword">if</span> <span class="library">table</span> == <span class="keyword">nil</span> <span class="keyword">then</span>
      <span class="library">table</span> = {}; <span class="library">rawset</span>(prevtable, atom, <span class="library">table</span>)
    <span class="keyword">elseif</span> <span class="library">type</span>(<span class="library">table</span>) ~= <span class="string">'table'</span> <span class="keyword">then</span>
      <span class="library">error</span>(<span class="string">'name conflict for module '</span> .. public._NAME, 4)
    <span class="keyword">end</span>
    prevatom = atom; prevprevtable = prevtable; prevtable = <span class="library">table</span>
  <span class="keyword">end</span>)
  <span class="library">rawset</span>(prevprevtable, prevatom, public)

  <span class="keyword">return</span> public
<span class="keyword">end</span>

<span class="comment">-- Declare module cleanly.</span>
<span class="comment">-- Create both public and private namespaces for module.</span>
<span class="comment">-- Global assignments inside module get placed in both</span>
<span class="comment">-- public and private namespaces.</span>
<span class="keyword">function</span> cleanmodule(modname)
  <span class="keyword">local</span> pubmt = {__call = import}
  <span class="keyword">local</span> pub = {import = import, _NAME = modname} <span class="comment">-- public namespace for module</span>
  <span class="keyword">local</span> priv = {_PUBLIC = pub, _PRIVATE = priv,
                _NAME = modname} <span class="comment">-- private namespace for module</span>
  <span class="keyword">local</span> privmt = {
    __index = <span class="library">_G</span>,
    __newindex = <span class="keyword">function</span>(priv, k, v)
      <span class="library">rawset</span>(pub, k, v)
      <span class="library">rawset</span>(priv, k, v)
    <span class="keyword">end</span>
  }
  <span class="library">setmetatable</span>(pub, pubmt)
  <span class="library">setmetatable</span>(priv, privmt)
  <span class="library">setfenv</span>(2, priv)

  pub:import(priv)

  <span class="library">package.loaded</span>[modname] = pub
<span class="keyword">end</span>
</pre>
</DL>
<p>
This is typically used in this way:<p>
<DL>
<dt><dd><pre class="code">
<span class="comment">-- somemodule.lua</span>
<span class="library">require</span> <span class="string">"cleanmodule"</span>
cleanmodule(...)

<span class="keyword">local</span> om = <span class="library">require</span> <span class="string">"othermodule"</span>

om.hello()

<span class="library">require</span> <span class="string">"othermodule"</span> ()

othermodule.hello()

<span class="library">require</span> <span class="string">"othermodule"</span> <span class="string">":all"</span>

hello()
</pre>
</DL>
<p>
The caller has full control in deciding how it wants to the called module to modify the caller's (private) namespace.<p>
One small problem you might run into is when setting a global twice:<p>
<DL>
<dt><dd><pre class="code">
cleanmodule(...)
<span class="keyword">local</span> enable_spanish = <span class="keyword">true</span>
<span class="keyword">function</span> test() <span class="library">print</span>(<span class="string">"hello"</span>) <span class="keyword">end</span>
<span class="keyword">if</span> enable_spanish <span class="keyword">then</span> test = <span class="keyword">function</span>() <span class="library">print</span>(<span class="string">"hola"</span>) <span class="keyword">end</span> <span class="keyword">end</span>
</pre>
</DL>
<p>
Here, the metamethod only activates on the first set, so the public namespace will incorrectly contain the first function defined above.  The work around is to explicitly set to <code>nil</code>:<p>
<DL>
<dt><dd><pre class="code">
cleanmodule(...)
<span class="keyword">local</span> enable_spanish = <span class="keyword">true</span>
<span class="keyword">function</span> test() <span class="library">print</span>(<span class="string">"hello"</span>) <span class="keyword">end</span>
<span class="keyword">if</span> enable_spanish <span class="keyword">then</span> test = <span class="keyword">nil</span>; test = <span class="keyword">function</span>() <span class="library">print</span>(<span class="string">"hola"</span>) <span class="keyword">end</span> <span class="keyword">end</span>
</pre>
</DL>
<p>
<em>(This example was originally in Lua<code></code>Design<code></code>Patterns.)</em><p>
--<a href="/wiki/DavidManura" >DavidManura</a>, 200703<p>
<p>
<H2>See Also</H2>
<p>
<UL>
<li> <a href="/wiki/ModulesTutorial" >ModulesTutorial</a><li> <a href="/wiki/LuaModuleFunctionCritiqued" >LuaModuleFunctionCritiqued</a><li> <a href="/wiki/BuildingModules" >BuildingModules</a><li> <a href="/wiki/LuaModulesLoader" >LuaModulesLoader</a><li> <a href="/wiki/ModuleExecutionProposal" >ModuleExecutionProposal</a></UL>
<hr>
<a href="/wiki/FindPage" >FindPage</a> &middot; <a href="/wiki/RecentChanges" >RecentChanges</a> &middot; <a href="/cgi-bin/wiki.pl?action=editprefs" >preferences</a><br>
<a href="/cgi-bin/wiki.pl?action=edit&amp;id=ModuleDefinition" >edit</a> &middot; <a href="/cgi-bin/wiki.pl?action=history&amp;id=ModuleDefinition" >history</a><br>Last edited October 19, 2008 2:06 am GMT <a href="/cgi-bin/wiki.pl?action=browse&amp;diff=1&amp;id=ModuleDefinition" >(diff)</a>
</body>
</html>